<template>
    <div>
        <div v-if="!url" v-loading="loading" :element-loading-text="loadingProgressText"
            element-loading-spinner="el-icon-loading">
            <el-upload class="upload-demo" :show-file-list="false" :drag="true" :auto-upload="false"
                :on-change="handleChange" :before-upload="beforeUpload" action="#" :accept="accept">
                <i class="el-icon-upload"></i>

            </el-upload>
        </div>
        <div v-else>
            <div class="preview-container" @mouseover="mouseover" @mouseleave="mouseleave">
                <video controls :src="src" class="preview-video" ref="preview" />
                <div class="delete-button-container">
                    <button class="custom-delete-button" @click="deleteVideo"
                        :class="{ hovered: deleteButtonHover ? true : false }">
                        <i class="el-icon-delete"></i>
                    </button>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    props: {
        url: { type: String, default: "" },
        prefix: { type: String, default: "topic/video" },
        accept: {
            type: String, default: ".mp4, .avi, .mov, .wmv, .flv, .mkv"
        },
        showToast: { type: Boolean, default: false },
    },
    data() {
        return {
            loading: false,
            src: this.url,
            deleteButtonHover: false,
            loadingProgressText: "",
        };
    },
    methods: {

        mouseover() {
            this.deleteButtonHover = true;
        },

        mouseleave() {
            this.deleteButtonHover = false;
        },

        handleChange(file) {
            if (file.status === "ready") {
                this.uploadFile(file.raw);
            }
        },
        beforeUpload(file) {
            const acceptedTypes = this.accept.toLowerCase().split(',').map(type => type.trim());
            const extension = file.name.slice((file.name.lastIndexOf(".") - 1 >>> 0) + 2).toLowerCase();
            const isValidType = acceptedTypes.includes('.' + extension);

            if (!isValidType) {
                this.$message.error(`只能上传以下类型的文件：${this.accept}`);
            }

            return isValidType;
        },

        async uploadFile(file) {
            const startTime = Date.now();
            try {
                this.loading = true;
                const res = await this.$fetch.cosUplod(file, `/assets/${this.prefix}`, {
    
                    onProgress: (percent, speed, total) => {
                        const current = (total * (percent * 0.01)).toFixed(2);
                        this.loadingProgressText = `${current}Mb / ${total}Mb ,  速度：${speed}Mb/s, 进度：${percent}%;`;
                    },
                    onFileFinish: () => {
                        this.loadingProgressText = "";
                        this.loading = false;

                    }
                });
                if (res) {
                    this.showToast && this.$message.success("视频上传成功！");
                    this.src = res;
                    this.getFirstFrame(file)
                } else {
                    throw new Error("视频上传失败");
                }
            } catch (error) {
                console.error("上传错误:", error);
                this.$message.error("视频上传出错，请重试！");
            } finally {
                const endTime = Date.now();
                console.log(`上传完成，耗时${(endTime - startTime) / 1000}秒`);
                this.loading = false;
            }
        },

        async deleteVideo() {
            const { code } = await this.$fetch.post("/api/cos-delete", {
                url: this.src,
            });
            if (code === 0) {
                this.src = "";
            }
        },

        update(src) {
            this.$emit("update:url", src);
        },

        extractFirstFrame(blob) {
            this.$emit("extractFirstFrame", blob)
        },



        getFirstFrame(file) {
            const video = document.createElement('video');
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');
            const url = URL.createObjectURL(file);
            video.src = url;

            video.muted = true

            video.play()

            let self = this;

            video.onloadeddata = function () {
                ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
                URL.revokeObjectURL(url);
                canvas.toBlob(function (blob) {
                    self.extractFirstFrame(blob)
                }, 'image/png'); 
            };
        }
    },

    watch: {
        src(newVal, oldVal) {
            if (newVal !== oldVal) {
                this.update(newVal)
            }
        }
    }
};
</script>

<style lang="less" scoped>
.preview-container {
    position: relative;
    display: inline-block;
}

.preview-video {
    max-width: 100%;
    height: auto;
}

.delete-button-container {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 2;
}

.custom-delete-button {
    background-color: rgba(255, 0, 0, 0.8);
    color: white;
    border: none;
    border-radius: 50%;
    padding: 4px;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.9s ease, transform 0.3s ease;
    transform: scale(0.8);
}

.hovered {
    opacity: 1;
    transform: scale(1);
}

.custom-delete-button i {
    font-size: 16px;
}

.upload-demo {
    display: flex;
    align-items: center;
}

::v-deep .el-upload-dragger {
    display: flex;
    justify-content: center;
    align-items: center;

    .el-icon-upload {
        margin: 0;
    }
}
</style>